package com.selfdiscipline.service

import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.selfdiscipline.R
import com.selfdiscipline.SelfDisciplineApp.Companion.CHANNEL_TIMER_ID
import com.selfdiscipline.SelfDisciplineApp.Companion.NOTIFICATION_TIMER_ID
import com.selfdiscipline.data.model.TimeRecord
import com.selfdiscipline.ui.MainActivity
import java.util.Date
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

/**
 * Foreground service for managing the focus timer
 */
class TimerService : Service() {
    
    private val binder = TimerBinder()
    private var timer: Timer? = null
    private var timerTask: TimerTask? = null
    private var elapsedTimeMillis: Long = 0
    private var startTime: Date? = null
    private var isTimerRunning = false
    private var currentTaskId: String? = null
    private var serviceJob: Job? = null
    
    // Coroutine scope for service operations
    private val serviceScope = CoroutineScope(Dispatchers.IO + Job())
    
    // Timer state
    private val _timerState = MutableStateFlow(TimerState())
    val timerState: StateFlow<TimerState> = _timerState.asStateFlow()
    
    override fun onCreate() {
        super.onCreate()
        // Initialize if needed
    }
    
    override fun onBind(intent: Intent?): IBinder {
        return binder
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_START -> startTimer(
                intent.getStringExtra(EXTRA_TASK_ID),
                intent.getIntExtra(EXTRA_DURATION_MINUTES, DEFAULT_TIMER_MINUTES)
            )
            ACTION_PAUSE -> pauseTimer()
            ACTION_RESUME -> resumeTimer()
            ACTION_STOP -> stopTimer()
        }
        
        return START_STICKY
    }
    
    /**
     * Start a new timer session
     */
    fun startTimer(taskId: String? = null, durationMinutes: Int = DEFAULT_TIMER_MINUTES) {
        if (isTimerRunning) {
            stopTimer()
        }
        
        startTime = Date()
        currentTaskId = taskId
        elapsedTimeMillis = 0
        
        val totalTimeMillis = TimeUnit.MINUTES.toMillis(durationMinutes.toLong())
        
        _timerState.value = TimerState(
            isRunning = true,
            elapsedMillis = 0,
            totalMillis = totalTimeMillis,
            taskId = taskId
        )
        
        startForeground(NOTIFICATION_TIMER_ID, createNotification())
        
        timer = Timer()
        timerTask = object : TimerTask() {
            override fun run() {
                elapsedTimeMillis += 1000
                
                if (elapsedTimeMillis >= totalTimeMillis) {
                    // Timer complete
                    timerComplete()
                } else {
                    // Update timer state
                    _timerState.value = _timerState.value.copy(
                        elapsedMillis = elapsedTimeMillis
                    )
                    
                    // Update notification
                    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                    notificationManager.notify(NOTIFICATION_TIMER_ID, createNotification())
                }
            }
        }
        
        timer?.scheduleAtFixedRate(timerTask, 1000, 1000)
        isTimerRunning = true
    }
    
    /**
     * Pause the current timer
     */
    fun pauseTimer() {
        timer?.cancel()
        timer = null
        timerTask = null
        isTimerRunning = false
        
        _timerState.value = _timerState.value.copy(
            isRunning = false
        )
        
        // Update notification
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(NOTIFICATION_TIMER_ID, createNotification())
    }
    
    /**
     * Resume the paused timer
     */
    fun resumeTimer() {
        if (isTimerRunning) return
        
        _timerState.value = _timerState.value.copy(
            isRunning = true
        )
        
        timer = Timer()
        timerTask = object : TimerTask() {
            override fun run() {
                elapsedTimeMillis += 1000
                
                if (elapsedTimeMillis >= _timerState.value.totalMillis) {
                    // Timer complete
                    timerComplete()
                } else {
                    // Update timer state
                    _timerState.value = _timerState.value.copy(
                        elapsedMillis = elapsedTimeMillis
                    )
                    
                    // Update notification
                    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                    notificationManager.notify(NOTIFICATION_TIMER_ID, createNotification())
                }
            }
        }
        
        timer?.scheduleAtFixedRate(timerTask, 1000, 1000)
        isTimerRunning = true
    }
    
    /**
     * Stop the timer completely
     */
    fun stopTimer() {
        timer?.cancel()
        timer = null
        timerTask = null
        
        if (startTime != null) {
            // Save the time record
            val endTime = Date()
            saveTimeRecord(endTime)
        }
        
        isTimerRunning = false
        elapsedTimeMillis = 0
        startTime = null
        currentTaskId = null
        
        _timerState.value = TimerState()
        
        stopForeground(true)
        stopSelf()
    }
    
    /**
     * Handle timer completion
     */
    private fun timerComplete() {
        timer?.cancel()
        timer = null
        timerTask = null
        isTimerRunning = false
        
        // Save the time record
        val endTime = Date()
        saveTimeRecord(endTime)
        
        _timerState.value = _timerState.value.copy(
            isRunning = false,
            isCompleted = true
        )
        
        // Update notification for completion
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(NOTIFICATION_TIMER_ID, createCompletionNotification())
    }
    
    /**
     * Save the time record to the database
     */
    private fun saveTimeRecord(endTime: Date) {
        val startTimeDate = startTime ?: return
        
        serviceScope.launch {
            val timeRecord = TimeRecord(
                startTime = startTimeDate,
                endTime = endTime,
                duration = endTime.time - startTimeDate.time,
                taskId = currentTaskId,
                isCompleted = true
            )
            
            // TODO: Save to repository once implemented
        }
    }
    
    /**
     * Create the active timer notification
     */
    private fun createNotification(): android.app.Notification {
        val activityIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            activityIntent,
            PendingIntent.FLAG_IMMUTABLE
        )
        
        // Action intents
        val pauseIntent = Intent(this, TimerService::class.java).apply {
            action = if (_timerState.value.isRunning) ACTION_PAUSE else ACTION_RESUME
        }
        val pausePendingIntent = PendingIntent.getService(
            this,
            1,
            pauseIntent,
            PendingIntent.FLAG_IMMUTABLE
        )
        
        val stopIntent = Intent(this, TimerService::class.java).apply {
            action = ACTION_STOP
        }
        val stopPendingIntent = PendingIntent.getService(
            this,
            2,
            stopIntent,
            PendingIntent.FLAG_IMMUTABLE
        )
        
        // Format time remaining
        val remainingMillis = _timerState.value.totalMillis - _timerState.value.elapsedMillis
        val minutes = TimeUnit.MILLISECONDS.toMinutes(remainingMillis)
        val seconds = TimeUnit.MILLISECONDS.toSeconds(remainingMillis) % 60
        val timeString = String.format("%02d:%02d", minutes, seconds)
        
        // Create notification
        return NotificationCompat.Builder(this, CHANNEL_TIMER_ID)
            .setSmallIcon(R.drawable.ic_timer)
            .setContentTitle(getString(R.string.timer_notification_title))
            .setContentText(timeString)
            .setContentIntent(pendingIntent)
            .setOngoing(true)
            .addAction(
                R.drawable.ic_pause,
                getString(if (_timerState.value.isRunning) R.string.timer_pause else R.string.timer_resume),
                pausePendingIntent
            )
            .addAction(
                R.drawable.ic_stop,
                getString(R.string.timer_stop),
                stopPendingIntent
            )
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setCategory(NotificationCompat.CATEGORY_ALARM)
            .build()
    }
    
    /**
     * Create the timer completion notification
     */
    private fun createCompletionNotification(): android.app.Notification {
        val activityIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            activityIntent,
            PendingIntent.FLAG_IMMUTABLE
        )
        
        return NotificationCompat.Builder(this, CHANNEL_TIMER_ID)
            .setSmallIcon(R.drawable.ic_timer_complete)
            .setContentTitle(getString(R.string.timer_notification_title))
            .setContentText(getString(R.string.timer_notification_complete))
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setCategory(NotificationCompat.CATEGORY_ALARM)
            .build()
    }
    
    /**
     * Binder class for client connection
     */
    inner class TimerBinder : Binder() {
        fun getService(): TimerService = this@TimerService
    }
    
    /**
     * Cleanup on destroy
     */
    override fun onDestroy() {
        super.onDestroy()
        timer?.cancel()
        timer = null
        timerTask = null
        serviceJob?.cancel()
    }
    
    companion object {
        const val ACTION_START = "com.selfdiscipline.service.action.START_TIMER"
        const val ACTION_PAUSE = "com.selfdiscipline.service.action.PAUSE_TIMER"
        const val ACTION_RESUME = "com.selfdiscipline.service.action.RESUME_TIMER"
        const val ACTION_STOP = "com.selfdiscipline.service.action.STOP_TIMER"
        
        const val EXTRA_TASK_ID = "com.selfdiscipline.service.extra.TASK_ID"
        const val EXTRA_DURATION_MINUTES = "com.selfdiscipline.service.extra.DURATION_MINUTES"
        
        const val DEFAULT_TIMER_MINUTES = 25
    }
}

/**
 * Timer state for the UI
 */
data class TimerState(
    val isRunning: Boolean = false,
    val elapsedMillis: Long = 0,
    val totalMillis: Long = 0,
    val taskId: String? = null,
    val isCompleted: Boolean = false
) 